package com.yb.personelmanagement.config.jwtconfig;

import com.yb.personelmanagement.config.jwt.JwtTokenUtil;
import com.yb.personelmanagement.domain.System.User;
import com.yb.personelmanagement.service.jwt.JwtUserDetailsService;
import io.jsonwebtoken.ExpiredJwtException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @Auther: lzx
 * @Date: 2019/8/7 16:06
 * @Description:在security中配置此过滤器
 * 该过滤器进行用户的校验校验
 */
@Component
@Slf4j
public class JwtAuthorizationTokenFilter extends OncePerRequestFilter {
    private final JwtUserDetailsService jwtUserDetailsService;
    private  final String tokenHeader;
    private final JwtTokenUtil jwtTokenUtil;

    public JwtAuthorizationTokenFilter(@Qualifier("jwtUserDetailsService")JwtUserDetailsService userDetailsService, @Value("${jwt.header}")  String tokenHeader, JwtTokenUtil jwtTokenUtil) {
        this.jwtUserDetailsService = userDetailsService;
        this.tokenHeader = tokenHeader;
        this.jwtTokenUtil = jwtTokenUtil;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {
        log.info("开始处理来自{}的认证",httpServletRequest.getRequestURL());
        final   String  requestHeader=httpServletRequest.getHeader(this.tokenHeader);
        String userName=null;
        String  tokenContent=null;
        //校验开始
        if(null!=requestHeader && requestHeader.startsWith("Bearer ")) {
            tokenContent = requestHeader.substring(7);
            try {
                //从token内容中获取用户名
                userName = jwtTokenUtil.getUsernameFromToken(tokenContent);
            } catch (IllegalArgumentException e) {
                log.info("从token获取用户名失败{}", userName);
            } catch (ExpiredJwtException e) {
                log.warn("token超时，请重新获取", e);
            }
        }
        else {
            log.error("请求头信息不合理{}不包括Bearer",requestHeader);
        }
           if(null!=userName && SecurityContextHolder.getContext().getAuthentication() == null){
               User isExistUser=null;

               //1、判断该用户是否存在
               try {
                   isExistUser= jwtUserDetailsService.loadUserByUsername(userName);

               } catch (UsernameNotFoundException e) {
                   httpServletResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED, e.getMessage());

                   return;
               }

               //2、用户存在的话判断token是否有效主要是否超时
               if (jwtTokenUtil.validateToken(tokenContent,isExistUser)) {
                   UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(isExistUser, null, isExistUser.getAuthorities());
                   authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(httpServletRequest));
                   log.info("认证用户{}，并添加上认证", userName);
                   SecurityContextHolder.getContext().setAuthentication(authentication);
               }
           }

      filterChain.doFilter(httpServletRequest,httpServletResponse);
    }
}
